#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXDRVFD 5

char    * welcome = NULL;
char    * distname = NULL;
char    * langset = NULL;
char    * kernelver = NULL;
char    * bootiso_fn = NULL;
char    * miimages_cddir = NULL;
unsigned  miinitrd_size = 0;
char    * hotfixdir = NULL;

char    * hdpathes[] = {
    NULL,                       /* replaced with distname */
    "",  /* / */
    "/tmp",
    "/boot",
    "/usr/share/MagicInstaller",
};
unsigned  num_hdpathes = sizeof(hdpathes) / sizeof(hdpathes[0]);

char *cdpathes[] = {
    NULL                        /* replaced with miimages_cddir */
};
unsigned  num_cdpathes = sizeof(cdpathes) / sizeof(cdpathes[0]);

char *drvfd[MAXDRVFD];
unsigned  num_drvfd;

/* S may be ruined. Use free() to release result memeory. */
char **strs_split(char *s,  char delim)
{
    char **res;
    int i;
    int n;
    int len;
    char *p;
    char **pp;

    if (s == NULL)
        return NULL;

    len = strlen(s);
    /* Replace delim char with null char. */
    n = 0;
    for (p = s; *p; p++) {
        if (*p == delim) {
            *p = '\0';
            n++;
        }
    }
    n++;

    res = (char**)malloc(n+1);
    if (!res)
        return NULL;
    /* update pointers */
    pp = res;
    for (i = 0; i < len; i++) {
        *(pp++) = s + i;
        /* skip to next substring start */
        while (i < len && s[i])
            i++;
    }
    *pp = NULL;                 /* the last one is NULL */
    return res;
}

int strs_len(char** strs)
{
    int res = 0;
    char **p;
    for (p = strs; p && *p; p++)
	res++;
    return res;
}

int  parse_config_file(const char *filename)
{
    int ok = 1;
    FILE *fp;
    char **split_values;
    char buf[512];

    /* Read the config in. */
    if ((fp = fopen(filename, "r")) == NULL) {
        fprintf(stderr, "Error read config file '%s'.\n", filename);
        return  0;
    }
    while (fgets(buf, sizeof(buf), fp) != NULL) {
        if (buf[strlen(buf) - 1] == '\n')
            buf[strlen(buf) - 1] = '\0';
        split_values = strs_split(buf, '=');
        if (!(split_values && strs_len(split_values) == 2)) {
            free(split_values);
            continue;
        }
#define GETTEXTVAL(var)                         \
        if (!strcmp(split_values[0], #var))      \
            var = strdup(split_values[1])
#define GETINTVAL(var)                          \
        if (!strcmp(split_values[0], #var))      \
            var = atoi(split_values[1])
        GETTEXTVAL(welcome);
        else GETTEXTVAL(distname);
        else GETTEXTVAL(langset);
        else GETTEXTVAL(kernelver);
        else GETTEXTVAL(bootiso_fn);
        else GETTEXTVAL(miimages_cddir);
        else GETTEXTVAL(hotfixdir);
        else GETINTVAL(miinitrd_size);
        else if (!strcmp(split_values[0], "drvfds")) {
            char **split_drvfds;

            num_drvfd = 0;
            split_drvfds = strs_split(split_values[1], ':');
            if (split_drvfds && strs_len(split_drvfds) >= 1) {
                while (split_drvfds[num_drvfd]) {
                    drvfd[num_drvfd] = strdup(split_drvfds[num_drvfd]);
                    num_drvfd++;
                }
            }
            free(split_drvfds);
        }
        free(split_values);
    }
    if (welcome == NULL
        || distname == NULL
        || langset == NULL
        || kernelver == NULL
        || bootiso_fn == NULL
        || miimages_cddir == NULL
        || hotfixdir == NULL
        || miinitrd_size == 0) {
        fprintf(stderr, "Error reading config value.\n");
        ok = 0;
        goto parse_config_file_exit;
    }
    hdpathes[0] = (char*)malloc(strlen(distname)+2);
    strcat(strcpy(hdpathes[0], "/"), distname);
    cdpathes[0] = (char*)malloc(strlen(miimages_cddir)+2);
    strcat(strcpy(cdpathes[0], "/"), miimages_cddir);
    /*printf("Size of miinitrd is %u\n", miinitrd_size);*/
#ifdef __SPEC_MAIN__
    {
        int i;

        printf("%s\n", welcome);
        printf("%s\n", distname);
        printf("%s\n", langset);
        printf("%s\n", kernelver);
        printf("%s\n", bootiso_fn);
        printf("%s\n", miimages_cddir);
        printf("%s\n", hotfixdir);
        printf("%u\n", miinitrd_size);
        printf("\nhdpathes:\n");
        for (i=0; i < num_hdpathes; i++)
            printf("\t%s\n", hdpathes[i]);
        printf("\ncdpathes:\n");
        for (i=0; i < num_cdpathes; i++)
            printf("\t%s\n", cdpathes[i]);
        printf("\ndrvfds:\n");
        for (i=0; i < num_drvfd; i++)
            printf("\t%s\n", drvfd[i]);
    }
#endif

  parse_config_file_exit:
    fclose(fp);
    return ok;
}

#undef GETTEXTVAL
#undef GETINTVAL

#ifdef __SPEC_MAIN__
int main(int argc, char *argv[])
{
    printf("%s\n", (parse_config_file("../etc/mbconfig.conf") ? "OK" : "BAD"));
    return 0;

}
#endif
